﻿#include "main_window.h"
#include "ui_MainWindow.h"

#include <QCloseEvent>
#include <QDebug>
#include <QDialog>
#include <QFileDialog>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QPushButton>
#include <QTextCodec>
#include <QTextStream>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
  ui->setupUi(this);

  QTextCodec* codec = QTextCodec::codecForName("GBK");
  current_file = codec->toUnicode("未命名.txt");
  setWindowTitle(current_file);

  // ui->statusBar->showMessage(codec->toUnicode("欢迎访问Qt爱好者社区！"),
  // 5000);
  statusLabel = new QLabel();
  statusLabel->setMinimumSize(150, 20);
  statusLabel->setFrameShape(QFrame::WinPanel);  // 设置标签形状
  statusLabel->setFrameShadow(QFrame::Sunken);   // 设置标签阴影
  ui->statusBar->addWidget(statusLabel);
  statusLabel->setText(codec->toUnicode("欢迎访问Qt爱好者社区！"));

  QLabel* permanent = new QLabel(this);
  permanent->setFrameStyle(QFrame::Box | QFrame::Sunken);
  permanent->setText(
      tr("<a href=\"http://www.yafeilinux.com\">yafeilinux.com</a>"));
  permanent->setTextFormat(Qt::RichText);
  permanent->setOpenExternalLinks(true);
  ui->statusBar->addPermanentWidget(permanent);

  find_dialog_ = new QDialog(this);
  find_dialog_->setWindowTitle(codec->toUnicode("查找"));
  find_lineedit_ = new QLineEdit(find_dialog_);
  QPushButton* next_button =
      new QPushButton(codec->toUnicode("查找下一个"), find_dialog_);
  QVBoxLayout* layout = new QVBoxLayout(find_dialog_);
  layout->addWidget(find_lineedit_);
  layout->addWidget(next_button);
  connect(next_button, &QPushButton::clicked, this, &MainWindow::ShowFindText);
}

MainWindow::~MainWindow() {
  delete ui;
  delete find_lineedit_;
  delete find_dialog_;
  delete statusLabel;
}

void MainWindow::NewFile() {
  if (MaybeSave()) {
    is_untitled = true;
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    current_file = codec->toUnicode("未命名.txt");
    setWindowTitle(current_file);
    ui->textEdit->clear();
    ui->textEdit->setVisible(true);
  }
}

bool MainWindow::MaybeSave() {
  if (ui->textEdit->document()->isModified()) {
    // 自定义一个警告对话框
    QMessageBox box;
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    box.setWindowTitle(codec->toUnicode("警告"));
    box.setIcon(QMessageBox::Warning);
    box.setText(current_file + codec->toUnicode(" 尚未保存，是否保存？"));
    QPushButton* yesBtn =
        box.addButton(codec->toUnicode("是(&Y)"), QMessageBox::YesRole);
    box.addButton(codec->toUnicode("否(&N)"), QMessageBox::NoRole);
    QPushButton* cancelBut =
        box.addButton(codec->toUnicode("取消"), QMessageBox::RejectRole);
    box.exec();

    if (box.clickedButton() == yesBtn) {
      return Save();
    } else if (box.clickedButton() == cancelBut) {
      return false;
    }
  }
  // 如果文档没有被更改，则直接返回true
  return true;
}

bool MainWindow::Save() {
  if (is_untitled) {
    return SaveAs();
  } else {
    return SaveFile(current_file);
  }
}

bool MainWindow::SaveAs() {
  QTextCodec* codec = QTextCodec::codecForName("GBK");
  QString fileName = QFileDialog::getSaveFileName(
      this, codec->toUnicode("另存为"), current_file);
  if (fileName.isEmpty())
    return false;
  return SaveFile(fileName);
}

bool MainWindow::SaveFile(const QString& file_name) {
  QFile file(file_name);

  if (!file.open(QFile::WriteOnly | QFile::Text)) {
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    QMessageBox::warning(this, codec->toUnicode("多文档编辑器"),
                         codec->toUnicode("无法写入文件 %1：/n %2")
                             .arg(file_name)
                             .arg(file.errorString()));
    return false;
  }
  QTextStream out(&file);
  // 鼠标指针变为等待状态
  QApplication::setOverrideCursor(Qt::WaitCursor);
  out << ui->textEdit->toPlainText();
  // 鼠标指针恢复原来的状态
  QApplication::restoreOverrideCursor();
  is_untitled = false;
  // 获得文件的标准路径
  current_file = QFileInfo(file_name).canonicalFilePath();
  setWindowTitle(current_file);
  return true;
}

bool MainWindow::LoadFile(const QString& fileName) {
  QFile file(fileName);  // 新建QFile对象
  QTextCodec* codec = QTextCodec::codecForName("GBK");
  if (!file.open(QFile::ReadOnly | QFile::Text)) {
    QMessageBox::warning(this, codec->toUnicode("多文档编辑器"),
                         codec->toUnicode("无法读取文件 %1:\n%2.")
                             .arg(fileName)
                             .arg(file.errorString()));
    return false;  // 只读方式打开文件，出错则提示，并返回false
  }

  QTextStream in(&file);
  QApplication::setOverrideCursor(Qt::WaitCursor);
  ui->textEdit->setPlainText(in.readAll());
  QApplication::restoreOverrideCursor();

  // 设置当前文件
  current_file = QFileInfo(fileName).canonicalFilePath();
  setWindowTitle(current_file);
  return true;
}

void MainWindow::on_action_New_triggered() {
  NewFile();
}

void MainWindow::on_action_Save_triggered() {
  Save();
}

void MainWindow::on_action_SaveAs_triggered() {
  SaveAs();
}

void MainWindow::on_action_Open_triggered() {
  if (MaybeSave()) {
    QString fileName = QFileDialog::getOpenFileName(this);
    if (!fileName.isEmpty()) {
      LoadFile(fileName);
      ui->textEdit->setVisible(true);
      is_untitled = false;
    }
  }
}

void MainWindow::on_action_Close_triggered() {
  if (MaybeSave()) {
    ui->textEdit->setVisible(false);
  }
}

void MainWindow::on_action_Exit_triggered() {
  if (MaybeSave()) {
    qApp->quit();
  }
}

void MainWindow::on_action_Undo_triggered() {
  ui->textEdit->undo();
}

void MainWindow::on_action_Cut_triggered() {
  ui->textEdit->cut();
}

void MainWindow::on_action_Copy_triggered() {
  ui->textEdit->copy();
}

void MainWindow::on_action_Paster_triggered() {
  ui->textEdit->paste();
}

void MainWindow::on_action_Find_triggered() {
  highlight_cursor_ = ui->textEdit->textCursor();
  find_dialog_->show();
}

void MainWindow::ShowFindText() {
  QString search_text = find_lineedit_->text();
  QTextDocument* document = ui->textEdit->document();
  QTextCursor cursor(document);

  QTextCharFormat color_format(highlight_cursor_.charFormat());
  color_format.setForeground(Qt::black);
  highlight_cursor_.mergeCharFormat(color_format);
  color_format.setForeground(Qt::red);

  cursor.beginEditBlock();
  highlight_cursor_ = document->find(search_text, highlight_cursor_);
  if (!highlight_cursor_.isNull()) {
    highlight_cursor_.mergeCharFormat(color_format);
  } else {
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    QMessageBox::information(this, codec->toUnicode("查找"),
                             codec->toUnicode("未查找到 ") + search_text);
  }
  cursor.endEditBlock();
}

void MainWindow::closeEvent(QCloseEvent* event) {
  if (MaybeSave()) {
    event->accept();
  } else {
    event->ignore();
  }
}
